﻿#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int i;
char **FORM=NULL;

/*用于URI解码*/
char x2c(char *what) 
{
    register char digit;
    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
    digit *= 16;
    digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
    return(digit);
}

/*unescape_url function*/

static void unescape_url(char *url)
{

	int x,y;

	for(x=0,y=0;url[y];++x,++y)
	{
		if((url[x]=url[y])=='%')
		{
			url[x]=x2c(&url[y+1]);
			y+=2;
		}
	}
	url[x]='\0';
}

/** Free anything that needs to be freed. **/
void PGFree(char **AAA)
	{
		for (i=0; AAA[i]; i++) 
			free(AAA[i]) ;
			free(AAA) ;
	}

/** Read the CGI input and place all name/val pairs into list.        **/
/** Returns list containing name1, value1, name2, value2, ... , NULL  **/
char **getcgivars()
{
     register int i ;
     char *request_method ;
     int content_length;
     char *cgiinput ;
     char **cgivars ;
     char **pairlist ;
     int paircount ;
     char *nvpair ;
     char *eqpos ;
	 static void unescape_url(char *url);

     /** Depending on the request method, read all CGI input into cgiinput.  **/
     request_method= getenv("REQUEST_METHOD") ;
     if (!strcmp(request_method, "GET") || !strcmp(request_method, "HEAD") )  
	{
         /* Some servers apparently don't provide QUERY_STRING if it's empty, */
         /*   so avoid strdup()'ing a NULL pointer here.                      */
         char *qs ;
         qs= getenv("QUERY_STRING") ;
         cgiinput= strdup(qs  ? qs  : "") ;
     }
     else if (!strcmp(request_method, "POST")) 
	 {
         /* strcasecmp() is not supported in Windows-- use strcmpi() instead */
         if (strcmp(getenv("CONTENT_TYPE"), "application/x-www-form-urlencoded")) 
		 {
			return 0;
         }
         if ( !(content_length = atoi(getenv("CONTENT_LENGTH"))) ) 
		 {
			printf("Content-Type: text/plain\n\n") ;
            printf("getcgivars(): No Content-Length was sent with the POSTrequest.\n") ;
            exit(1) ;
         }
         if ( !(cgiinput= (char *) malloc(content_length+1)))
		 {
			printf("Content-Type: text/plain\n\n") ;
            printf("getcgivars(): Couldn't malloc for cgiinput.\n") ;
            exit(1) ;
         }
         if (!fread(cgiinput, content_length, 1, stdin)) 
		 {
			printf("Content-Type: text/plain\n\n") ;
            printf("getcgivars(): Couldn't read CGI input from STDIN.\n") ;
            exit(1) ;
         }
         cgiinput[content_length]='\0' ;
	 }
     else 
	 {
		printf("Content-Type: text/plain\n\n") ;
        printf("getcgivars(): Unsupported REQUEST_METHOD.\n") ;
        exit(1) ;
     }

     /** Change all plusses back to spaces. **/
     for (i=0; cgiinput[i]; i++) if (cgiinput[i] == '+') 
		 cgiinput[i] = ' ' ;

     /** First, split on "&" and ";" to extract the name-value pairs into **/
     /**   pairlist.                                                      **/
     pairlist= (char **) malloc(256*sizeof(char **)) ;
     paircount= 0 ;
     nvpair= strtok(cgiinput, "&;") ;
     while (nvpair) 
	 {
        pairlist[paircount++]= strdup(nvpair) ;
        if (!(paircount%256))
             pairlist= (char **)  
		realloc(pairlist,(paircount+256)*sizeof(char **)) ;
        nvpair= strtok(NULL, "&;") ;
     }
     pairlist[paircount]= 0 ;    /* terminate the list with NULL */

     /** Then, from the list of pairs, extract the names and values. **/
     cgivars= (char **) malloc((paircount*2+1)*sizeof(char **)) ;
     for (i= 0; i<paircount; i++) 
	 {
         if (eqpos=strchr(pairlist[i], '=')) 
		 {
             *eqpos= '\0' ;
             unescape_url(cgivars[i*2+1]= strdup(eqpos+1)) ;
         } 
		 else 
		 {
             unescape_url(cgivars[i*2+1]= strdup("")) ;
         }
         unescape_url(cgivars[i*2]= strdup(pairlist[i])) ;
     }
     cgivars[paircount*2]= 0 ;   /* terminate the list with NULL */

     /** Free anything that needs to be freed. **/
     free(cgiinput) ;
	 PGFree(pairlist);
     /** Return the list of name-value strings. **/
     return cgivars ;
}
/////////////////////Get environment variable end//////////////////////////////


	
void Page_0()
	{
		printf("<html>\n");
		printf("<head><title>CGI Output</title></head>\n");
		printf("<body>\n");
		printf("<form method=post action=/cgi-bin/helloworld.cgi>\n");
		printf("<input type= text size=30 maxlength=30 name=aa>");
		//printf("<input type= text size=30 maxlength=30 name=aa>Operate P1<BR>");
		printf("<input type=submit value=提交>\n");
		printf("</form>\n");
		printf("</body>\n");
		printf("</html>\n");
	}

void Page_1()
	{
		printf("<html>\n");
		printf("<head><title>CGI Output</title></head>\n");
		printf("<body>\n");
		printf("<ul>\n");
		for (i=0; FORM[i]; i+= 2)
		printf("%s\n",FORM[i+1]);
		printf("</ul>\n") ;
		printf("</body>\n");
		printf("</html>\n");
	}

int main(void)
{	
	int i,flag=0,content_length=0;
	char menu[50]={0},submit[50]={0},*tmp=NULL;
    printf("Content-type: text/html\n\n");
	/* 产生默认页面 */
	Page_0();	
    
	if(tmp=getenv("CONTENT_LENGTH")) /* getenv??? */
	{
		content_length = atoi(tmp);
	}
	if (content_length > 0)
	{
		if(FORM=getcgivars())/* ??? */
		{
			Page_1();
			/** Free anything that needs to be freed **/
			PGFree(FORM);
		}
		else	{ return; }
	}
	exit(0);
}	